winsafe\oleaut\structs/
structs_other.rs

1#![allow(non_snake_case)]
2
3use std::marker::PhantomData;
4use std::mem::ManuallyDrop;
5
6use crate::co;
7use crate::decl::*;
8use crate::kernel::{ffi_types::*, privs::*};
9use crate::oleaut::ffi;
10
11/// [`DISPPARAMS`](https://learn.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-dispparams)
12/// struct.
13#[repr(C)]
14pub struct DISPPARAMS<'a, 'b> {
15	rvarg: *mut VARIANT, // in reverse order
16	rgdispidNamedArgs: *mut co::DISPID,
17	cArgs: u32,
18	cNamedArgs: u32,
19
20	_rvar: PhantomData<&'a mut VARIANT>,
21	_rgdispidNamedArgs: PhantomData<&'b mut co::DISPID>,
22}
23
24impl_default!(DISPPARAMS, 'a, 'b);
25
26impl<'a, 'b> DISPPARAMS<'a, 'b> {
27	pub_fn_array_buf_get_set!('a, rvarg, set_rvarg, cArgs, VARIANT);
28	pub_fn_array_buf_get_set!('b, rgdispidNamedArgs, set_rgdispidNamedArgs, cNamedArgs, co::DISPID);
29}
30
31/// [`EXCEPINFO`](https://learn.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-excepinfo)
32/// struct.
33///
34/// This struct is returned in case of remote exception by
35/// [`IDispatch::Invoke`](crate::prelude::oleaut_IDispatch::Invoke); in order to
36/// provide full security, it implements the standard [`Drop`](std::ops::Drop)
37/// trait to free the [`BSTR`](crate::BSTR) pointers.
38#[repr(C)]
39pub struct EXCEPINFO {
40	pub wCode: u16,
41	wReserved: u16,
42	bstrSource: *mut u16,
43	bstrDescription: *mut u16,
44	bstrHelpFile: *mut u16,
45	pub dwHelpContext: u32,
46	pvReserved: *mut std::ffi::c_void,
47	pfnDeferredFillIn: *mut std::ffi::c_void,
48	pub scode: i32,
49}
50
51unsafe impl Send for EXCEPINFO {}
52unsafe impl Sync for EXCEPINFO {}
53
54impl Drop for EXCEPINFO {
55	fn drop(&mut self) {
56		if !self.bstrSource.is_null() {
57			let _ = unsafe { BSTR::from_ptr(self.bstrSource) };
58		}
59		if !self.bstrDescription.is_null() {
60			let _ = unsafe { BSTR::from_ptr(self.bstrDescription) };
61		}
62		if !self.bstrHelpFile.is_null() {
63			let _ = unsafe { BSTR::from_ptr(self.bstrHelpFile) };
64		}
65	}
66}
67
68impl std::error::Error for EXCEPINFO {
69	fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
70		None
71	}
72}
73
74impl std::fmt::Display for EXCEPINFO {
75	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76		write!(
77			f,
78			"{} - {}",
79			self.bstrSource().unwrap_or("(no source)".to_owned()),
80			self.bstrDescription()
81				.unwrap_or("(no description)".to_owned()),
82		)
83	}
84}
85impl std::fmt::Debug for EXCEPINFO {
86	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87		std::fmt::Display::fmt(self, f)
88	}
89}
90
91impl_default!(EXCEPINFO);
92
93impl EXCEPINFO {
94	pub_fn_bstr_get!(bstrSource);
95	pub_fn_bstr_get!(bstrDescription);
96	pub_fn_bstr_get!(bstrHelpFile);
97}
98
99/// [`PROPVARIANT`](https://learn.microsoft.com/en-us/windows/win32/api/propidlbase/ns-propidlbase-propvariant)
100/// struct.
101///
102/// Should be manipulated through the [`PropVariant`](crate::PropVariant) enum.
103#[repr(C)]
104pub struct PROPVARIANT {
105	pub(crate) vt: co::VT,
106	wReserved1: u16,
107	wReserved2: u16,
108	wReserved3: u16,
109	pub(crate) data: PROPVARIANT_union,
110}
111
112#[repr(C)]
113pub(crate) union PROPVARIANT_union {
114	pub(crate) cVal: i8,
115	pub(crate) bVal: u8,
116	pub(crate) iVal: i16,
117	pub(crate) uiVal: u16,
118	pub(crate) lVal: i32,
119	pub(crate) ulVal: u32,
120	pub(crate) hVal: i64,
121	pub(crate) uhVal: u64,
122	pub(crate) fltVal: f32,
123	pub(crate) dblVal: f64,
124	pub(crate) ptr: *mut std::ffi::c_void, // for all pointer fields
125	pub(crate) cac: ManuallyDrop<CAC>,
126}
127
128#[repr(C)]
129pub(crate) struct CAC {
130	cElems: u32,
131	pElems: *mut i8,
132}
133
134impl Drop for PROPVARIANT {
135	fn drop(&mut self) {
136		if self.vt() != co::VT::EMPTY {
137			unsafe {
138				ffi::PropVariantClear(self as *mut _ as _); // ignore errors
139			}
140		}
141	}
142}
143
144impl_default!(PROPVARIANT); // PropVariantInit() is just a macro
145
146impl PROPVARIANT {
147	/// Returns the [`co::VT`](crate::co::VT) variant type currently being held.
148	#[must_use]
149	pub const fn vt(&self) -> co::VT {
150		self.vt
151	}
152}
153
154/// [`VARIANT`](https://learn.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-variant)
155/// struct.
156///
157/// Should be manipulated through the [`Variant`](crate::Variant) enum.
158#[repr(C)]
159pub struct VARIANT {
160	pub(crate) vt: co::VT,
161	wReserved1: u16,
162	wReserved2: u16,
163	wReserved3: u16,
164	pub(crate) data: VARIANT_union,
165}
166
167#[repr(C)]
168pub(crate) union VARIANT_union {
169	pub(crate) llVal: i64,
170	pub(crate) lVal: i32,
171	pub(crate) bVal: u8,
172	pub(crate) iVal: i16,
173	pub(crate) fltVal: f32,
174	pub(crate) dblVal: f64,
175	pub(crate) cVal: i8,
176	pub(crate) uiVal: u16,
177	pub(crate) ulVal: u32,
178	pub(crate) ullVal: u64,
179	pub(crate) ptr: *mut std::ffi::c_void, // for all pointer fields
180	pub(crate) brecord: ManuallyDrop<BRECORD>,
181}
182
183#[repr(C)]
184pub(crate) struct BRECORD {
185	pvRecord: *mut std::ffi::c_void,
186	pRecInfo: COMPTR,
187}
188
189impl Drop for VARIANT {
190	fn drop(&mut self) {
191		if self.vt != co::VT::EMPTY {
192			unsafe {
193				ffi::VariantClear(self as *mut _ as _); // ignore errors
194			}
195		}
196	}
197}
198
199impl Default for VARIANT {
200	fn default() -> Self {
201		let mut obj = unsafe { std::mem::zeroed::<Self>() };
202		unsafe {
203			ffi::VariantInit(pvoid(&mut obj));
204		}
205		obj
206	}
207}
208
209impl VARIANT {
210	/// Returns the [`co::VT`](crate::co::VT) variant type currently being held.
211	#[must_use]
212	pub const fn vt(&self) -> co::VT {
213		self.vt
214	}
215}